//package org.example.encrypt.dataBase;
//
//import cn.hutool.core.collection.CollUtil;
//import cn.hutool.core.date.DateTime;
//import cn.hutool.core.date.DateUtil;
//import cn.hutool.core.util.StrUtil;
//import cn.hutool.extra.spring.SpringUtil;
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
//import com.baomidou.mybatisplus.extension.service.IService;
//import lombok.extern.slf4j.Slf4j;
//import org.example.encrypt.annotations.CryptClass;
//import org.example.encrypt.annotations.CryptField;
//import org.example.encrypt.utils.AESUtil;
//import org.example.encrypt.utils.CryptUtil;
//import org.example.encrypt.utils.NumberCryptUtil;
//import org.springframework.stereotype.Component;
//import org.springframework.transaction.annotation.Transactional;
//
//import java.lang.reflect.Field;
//import java.math.BigDecimal;
//import java.util.*;
//
///**
// * 刷的时候把加解密拦截器关掉哈，不然是错误的！！！
// *
// * @Author WeiBing
// * @Create 2024/8/21 11:56
// */
//@Component
//@Slf4j
//public class DataBaseService {
//
//    /**
//     * 字符类型
//     */
//    private final List<Class<?>> STRING_CLASSES = Collections.singletonList(String.class);
//    /**
//     * 数值类型
//     */
//    private final List<Class<?>> NUMBER_CLASSES = Arrays.asList(BigDecimal.class, Integer.class, Double.class);
//
//    private static final Date UPDATE_TIME = DateUtil.parse("2024-09-15 03:00:00");
//
//    /**
//     * 实际的批量加密处理逻辑
//     * 要是失败了立刻回滚
//     */
//    @Transactional(rollbackFor = Exception.class)
//    public <T> void realCryptHandle(IService<T> service, Boolean encryptFlag) throws IllegalAccessException {
//        if (null == service) {
//            return;
//        }
//        if (null == encryptFlag) {
//            throw new RuntimeException("必须指明是加密还是解密操作");
//        }
//        int current = 1;
//        int size = 500;
//
//        // 循环控制字段
//        int realSize = 500;
//        while (realSize >= 500) {
//            Page<T> page = Page.of(current, size);
//            service.page(page);
//            List<T> records = page.getRecords();
//
//            // 循环处理每条数据里面的敏感字段
//            if (CollUtil.isNotEmpty(records)) {
//                // 过滤一：先判断这个类型是不是要加解密的类型，如果不是，直接结束，啥也不干
//                T t = records.get(0);
//                Class<?> aClass = t.getClass();
//                boolean classAnnotationPresent = aClass.isAnnotationPresent(CryptClass.class);
//                if (!classAnnotationPresent) {
//                    return;
//                }
//
//                // 过滤二：获取里面所有需要加解密的字段，如果没有要加解密的字段，那也是啥也不干
////                Field[] declaredFields = aClass.getDeclaredFields();
//                Field[] allFields = CryptUtil.getAllFields(aClass);
//                ArrayList<Field> needCryptFields = new ArrayList<>();
//                for (Field field : allFields) {
//                    CryptField cryptField = field.getAnnotation(CryptField.class);
//                    if (null == cryptField) {
//                        continue;
//                    }
//                    boolean encrypt = cryptField.encrypt();
//                    boolean decrypt = cryptField.decrypt();
//                    if (encryptFlag) {
//                        if (encrypt) {
//                            needCryptFields.add(field);
//                        }
//                    } else {
//                        if (decrypt) {
//                            needCryptFields.add(field);
//                        }
//                    }
//                }
//                if (CollUtil.isEmpty(needCryptFields)) {
//                    return;
//                }
//
//                // 过滤三：判断数据是否需要修改（是否已被加密）
//                ArrayList<T> result = new ArrayList<>();
//                for (T record : records) {
//
//                    try {
//                        Field updateTime = aClass.getDeclaredField("updateTime");
//                        updateTime.setAccessible(true);
//                        Object updateTimeObj = updateTime.get(record);
//                        String updateTimeStr = String.valueOf(updateTimeObj);
//                        DateTime oriUpdateTime = DateUtil.parse(updateTimeStr);
//                        // 时间相同，说明已被修改过，则跳过不处理
//                        if (DateUtil.compare(oriUpdateTime, UPDATE_TIME) == 0) {
//                            log.info("数据重复加密，原修改时间：{}，现修改时间：{},record:{}", oriUpdateTime.toString(), UPDATE_TIME.toString(), record);
//                            continue;
//                        } else {
//                            // 数据需要修改的话，再把updateTime字段给更新了
//                            updateTime.set(record, UPDATE_TIME);
//                            result.add(record);
//                        }
//                    } catch (Exception e) {
//                        log.error("未获取到表对象的updateTime属性");
//                        continue;
//                    }
//
//                    // 能走到这里说明数据没被加密过，且有需要加解密的敏感字段
//                    for (Field field : needCryptFields) {
//                        field.setAccessible(true);
//                        Class<?> fieldType = field.getType();
//                        Object fieldValue = field.get(record);
//
//                        // 如果值是null，那就跳过不处理
//                        if (null == fieldValue) {
//                            continue;
//                        }
//
//                        // 得根据属性类型来判断是做AES加解密还是XOR加解密
//                        if (STRING_CLASSES.contains(fieldType)) {
//                            // 对属性值进行AES加解密
//                            // 对老旧数据trim以下，字符串类型的发现有空格存在，所以特殊处理一下
//                            String strValue = String.valueOf(fieldValue);
//                            strValue = strValue.trim();
//                            field.set(record, encryptFlag ? AESUtil.encrypt(strValue) : AESUtil.decrypt(strValue));
//                        } else if (NUMBER_CLASSES.contains(fieldType)) {
//                            // 对属性值进行XOR加解密
//                            if (BigDecimal.class.equals(fieldType)) {
//                                BigDecimal numberValue = (BigDecimal)fieldValue;
//                                field.set(record, encryptFlag ? NumberCryptUtil.encrypt(numberValue) : NumberCryptUtil.decrypt(numberValue));
//                            } else if (Integer.class.equals(fieldType)) {
//                                int numberValue = (Integer)fieldValue;
//                                field.set(record, encryptFlag ? NumberCryptUtil.encrypt(BigDecimal.valueOf(numberValue)) : NumberCryptUtil.decrypt(BigDecimal.valueOf(numberValue)));
//                            } else if (Double.class.equals(fieldType)) {
//                                double numberValue = (Double)fieldValue;
//                                field.set(record, encryptFlag ? NumberCryptUtil.encrypt(BigDecimal.valueOf(numberValue)) : NumberCryptUtil.decrypt(BigDecimal.valueOf(numberValue)));
//                            }
//                        } else {
//                            // 其他类型就别管
//                            log.info("不支持加解密的字段类型");
//                        }
//                    }
//                }
//
//                // 一次性改
//                try {
//                    if (CollUtil.isNotEmpty(result)) {
//                        service.saveOrUpdateBatch(result);
//                    } else {
//                        log.info("没有需要修改的数据");
//                    }
//                } catch (Exception e) {
//                    log.error("修改失败，当前页：{}，失败原因：{}", current, e.getMessage());
//                    throw new RuntimeException(e);
//                }
//
//            }
//            // 维护循环控制字段
//            current++;
//            realSize = records.size();
//        }
//    }
//
//    /**
//     * 根据表名获取表对应的service操作对象
//     */
//    public IService<?> getTableServiceByTableName(String tableName) {
//        if (StrUtil.isBlank(tableName)) {
//            log.info("表名为空");
//            return null;
//        }
//        tableName = tableName.trim();
//        // 涉及到敏感字段的各种判断了。。。
//        /*switch (tableName) {
//            case "t_br_analyze_result" :
//                return SpringUtil.getBean(BrAnalyzeResultService.class);
//            case "t_br_detail" :
//                return SpringUtil.getBean(IBrDetailService.class);
//            case "t_collect_education" :
//                return SpringUtil.getBean(CollectEducationService.class);
//            case "t_employee_base_info" :
//                return SpringUtil.getBean(IEmployeeBaseInfoService.class);
//            case "t_employee_bonus_particulars" :
//                return SpringUtil.getBean(IEmployeeBonusParticularsService.class);
//            case "t_employee_contract" :
//                return SpringUtil.getBean(EmployeeContractService.class);
//            case "t_employee_contract_modify" :
//                return SpringUtil.getBean(IEmployeeContractModifyService.class);
//            case "t_employee_credit_info" :
//                return SpringUtil.getBean(IEmployeeCreditInfoService.class);
//            case "t_employee_cs_base_info" :
//                return SpringUtil.getBean(IEmployeeCsBaseInfoService.class);
//            case "t_employee_cs_contract_info" :
//                return SpringUtil.getBean(IEmployeeCsContractInfoService.class);
//            case "t_employee_cs_education_info" :
//                return SpringUtil.getBean(IEmployeeCsEducationInfoService.class);
//            case "t_employee_cs_family_info" :
//                return SpringUtil.getBean(IEmployeeCsFamilyInfoService.class);
//            case "t_employee_cs_sspfs_info" :
//                return SpringUtil.getBean(IEmployeeCsSspfsInfoService.class);
//            case "t_employee_cs_work_record_info" :
//                return SpringUtil.getBean(IEmployeeCsWorkRecordInfoService.class);
//            case "t_employee_edit_base_info" :
//                return SpringUtil.getBean(IEmployeeEditBaseInfoService.class);
//            case "t_employee_edit_family_info" :
//                return SpringUtil.getBean(IEmployeeEditFamilyInfoService.class);
//            case "t_employee_edit_work_info" :
//                return SpringUtil.getBean(IEmployeeEditWorkInfoService.class);
//            case "t_employee_education" :
//                return SpringUtil.getBean(IEmployeeEducationService.class);
//            case "t_employee_family" :
//                return SpringUtil.getBean(IEmployeeFamilyService.class);
//            case "t_employee_id_card_info" :
//                return SpringUtil.getBean(IEmployeeIdCardInfoService.class);
//            case "t_employee_month_end" :
//                return SpringUtil.getBean(IEmployeeMonthEndService.class);
//            case "t_employee_process_hire" :
//                return SpringUtil.getBean(IEmployeeProcessHireService.class);
//            case "t_employee_sspfs" :
//                return SpringUtil.getBean(IEmployeeSspfsService.class);
//            case "t_employee_sspfs_modify" :
//                return SpringUtil.getBean(IEmployeeSspfsModifyService.class);
//            case "t_employee_sspfs_month_end" :
//                return SpringUtil.getBean(IEmployeeSspfsMonthEndService.class);
//            case "t_family_relation" :
//                return SpringUtil.getBean(FamilyRelationService.class);
//            case "t_resume_collect" :
//                return SpringUtil.getBean(ResumeCollectService.class);
//            case "t_settlement_social_security" :
//                return SpringUtil.getBean(ISettlementSocialSecurityService.class);
//            case "t_transfer_salary" :
//                return SpringUtil.getBean(ITransferSalaryService.class);
//            case "t_work_record" :
//                return SpringUtil.getBean(WorkRecordService.class);
//            case "t_employee_salary_detail" :
//                return SpringUtil.getBean(IEmployeeSalaryDetailService.class);
//        }*/
//        log.info("未根据表名获取到对应的service操作类，tableName:{}", tableName);
//        return null;
//    }
//
//
//}
